package blaze.homebank.client;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;

/**
 * Entry point classes define <code>onModuleLoad()</code>.
 */
public class Homebank implements EntryPoint {
	/**
	 * The message displayed to the user when the server cannot be reached or
	 * returns an error.
	 */
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";

	
	private VerticalPanel mainPanel = new VerticalPanel();
	private HorizontalPanel linkPanel = new HorizontalPanel();
	
	
	// homes
	private HomeServiceAsync homeService = GWT.create(HomeService.class);
	private VerticalPanel homePanel = new VerticalPanel();
	private Grid homesGrid = new Grid(10, 3);
	private List<Home> homes = new ArrayList<Home>();

	//login/logout using google services
	private LoginServiceAsync loginService = GWT.create(LoginService.class);
	private LoginInfo loginInfo = null;
	private VerticalPanel loginPanel = new VerticalPanel();
	private Label loginLabel = new Label("Please sign in to your Google Account to access the Homebank application.");
	private Anchor signInLink = new Anchor("Sign In");
	private Anchor signOutLink = new Anchor("Sign Out");

	/**
	 * This is the entry point method.
	 */
	public void onModuleLoad() {
		mainPanel.add(linkPanel);
		
		// Check login status using login service.
		loginService.login(GWT.getHostPageBaseURL(), new AsyncCallback<LoginInfo>() {
			public void onFailure(Throwable error) {
			}

			public void onSuccess(LoginInfo result) {
				loginInfo = result;
				if (loginInfo.isLoggedIn()) {
					loadApp();
				} else {
					loadLogin();
				}
			}
		});
	}

	private void loadLogin() {
		// Assemble login panel.
		signInLink.setHref(loginInfo.getLoginUrl());
		loginPanel.add(loginLabel);
		loginPanel.add(signInLink);
		RootPanel.get("mainPanel").add(loginPanel);
	}
	  
	private void loadApp() {
	    // Associate the Main panel with the HTML host page.
	    RootPanel.get("mainPanel").add(mainPanel);
	    mainPanel.add(homePanel);
	    homePanel.add(homesGrid);
	    
	    
	    // Create the popup dialog box
		final DialogBox dialogBox = new DialogBox();
		dialogBox.setText("Add new Home");
		dialogBox.setAnimationEnabled(true);
		final Button closeButton = new Button("Close");
		final Button addButton = new Button("Add");
		final TextBox nameField = new TextBox();
		final TextBox descField = new TextBox();
		// We can set the id of a widget by accessing its Element
		closeButton.getElement().setId("closeButton");
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");
		dialogVPanel.add(new HTML("<b>Home name:</b>"));
		dialogVPanel.add(nameField);
		dialogVPanel.add(new HTML("<br><b>Home description:</b>"));
		dialogVPanel.add(descField);
		dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		dialogVPanel.add(addButton);
		dialogVPanel.add(closeButton);
		dialogBox.setWidget(dialogVPanel);
		
		addButton.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				final Home home = new Home(homes.size(), nameField.getText(), descField.getText());
				
				homeService.addHome(loginInfo, home, new AsyncCallback<Boolean>() {
					@Override
					public void onSuccess(Boolean result) {
						if (result) {
							homes.add(home);
							dialogBox.hide();
							fillHomes();
						}
					}
					
					@Override
					public void onFailure(Throwable caught) {
						// TODO Auto-generated method stub
						
					}
				});
			}
		});
		
		
		// Add a handler to close the DialogBox
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();
			}
		});
	    
	    
	    Button addHome = new Button("Add home");
	    addHome.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				dialogBox.center();
				closeButton.setFocus(true);
			}
		});
	    homePanel.add(addHome);
	    
	    //load other panels
		loadHomes();
		Anchor homesLink = new Anchor("Homes");
		homesLink.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				loadHomes();
			}
		});
		linkPanel.add(homesLink);
		
		// Set up sign out hyperlink.
	    signOutLink.setHref(loginInfo.getLogoutUrl());
	    signOutLink.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
	    linkPanel.add(signOutLink);
	}
	
	private void loadHomes() {
		homeService.getHomes(loginInfo, new AsyncCallback<Home[]>() {
			public void onFailure(Throwable error) {
			}

			@Override
			public void onSuccess(Home[] result) {
				if (result != null) {
					homes.clear();
					for (Home home: result) {
						homes.add(home);
					}
					fillHomes();
				}
			}
		});
	}
	
	private void fillHomes() {
		for (int i = 0; i < homes.size(); i++) {
			homesGrid.setText(i, 0, "" + homes.get(i).getId());
			homesGrid.setText(i, 1, homes.get(i).getName());
			homesGrid.setText(i, 2, homes.get(i).getDescription());
		}
	}
}
